home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / comms / internet / html-related / hsc / source / hsclib / uri.c < prev    next >
C/C++ Source or Header  |  1996-09-18  |  12KB  |  441 lines

  1. /*
  2.  * uri.c
  3.  *
  4.  * functions for uri parsing of tag arguments
  5.  *
  6.  * Copyright (C) 1995,96  Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated: 18-Sep-1996
  23.  * created: 16-Jul-1995
  24.  */
  25.  
  26. #define NOEXTERN_HSCLIB_URI_H
  27.  
  28. #include "ugly/fname.h"
  29.  
  30. #include "hsclib/inc_base.h"
  31. #include "hsclib/idref.h"
  32. #include "hscprj/project.h"
  33. #include "hsclib/uri.h"
  34.  
  35. #define PARENT_URI "../"        /* string for parent dir within URIs */
  36.  
  37. /*
  38.  * conv_path2uri
  39.  *
  40.  * convert a path for local (system-dependant)
  41.  * file system to URI
  42.  */
  43. VOID conv_path2uri(EXPSTR * dest, STRPTR path)
  44. {
  45.     clr_estr(dest);
  46.  
  47. #ifdef AMIGA
  48.     /* replace leading parent directories by "../" */
  49.     while (!strncmp(path, PARENT_DIR, strlen(PARENT_DIR)))
  50.     {
  51.         app_estr(dest, PARENT_URI);
  52.         path += strlen(PARENT_DIR);
  53.     }
  54.  
  55.     while (path[0])
  56.     {
  57.         /* replace all "//" by "../" */
  58.         if ((path[0] == '/') && (path[1] == '/'))
  59.         {
  60.             app_estr(dest, PARENT_URI);
  61.             path += 2;
  62.         }
  63.         else
  64.         {
  65.             app_estrch(dest, path[0]);
  66.             path++;
  67.         }
  68.     }
  69.  
  70. #elif defined MSDOS
  71.     /* replace all "\" by "/" */
  72.     while (path[0])
  73.     {
  74.         if ((path[0] == '\\'))
  75.             app_estrch(dest, '/');
  76.         else
  77.             app_estrch(dest, path[0]);
  78.         path++;
  79.     }
  80.  
  81. #elif defined UNIX
  82.     /* simply copy path */
  83.     set_estr(dest, path);
  84. #else
  85. #error "system not supported: conv_path2uri"
  86. #endif
  87. }
  88.  
  89. /*
  90.  * conv_uri2path
  91.  *
  92.  * convert a uri to a path for local (system-dependant)
  93.  * file system
  94.  */
  95. VOID conv_uri2path(EXPSTR * dest, STRPTR uri)
  96. {
  97.     clr_estr(dest);
  98.  
  99. #ifdef AMIGA
  100.     /* convert leading "../" to "/" */
  101.     while (!strncmp(uri, PARENT_URI, strlen(PARENT_URI)))
  102.     {
  103.         app_estr(dest, PARENT_DIR);
  104.         uri += strlen(PARENT_URI);
  105.     }
  106.  
  107.     /* convert inside "../" to "//" */
  108.     while (uri[0])
  109.     {
  110.         if (!strncmp(uri, PARENT_URI, strlen(PARENT_URI)))
  111.         {
  112.             app_estrch(dest, '/');
  113.             uri += strlen(PARENT_URI);
  114.         }
  115.         else
  116.         {
  117.             app_estrch(dest, uri[0]);
  118.             uri++;
  119.         }
  120.     }
  121.  
  122. #elif defined MSDOS
  123.     /* convert all "/" to "\" */
  124.     while (uri[0])
  125.     {
  126.         if (uri[0] == '/')
  127.             app_estrch(dest, '\\');
  128.         else
  129.             app_estrch(dest, uri[0]);
  130.         uri++;
  131.     }
  132.  
  133. #elif defined UNIX
  134.     set_estr(dest, uri);
  135. #else
  136. #error "system not supported: conv_2path"
  137. #endif
  138. }
  139.  
  140. /*
  141.  * uri_kind
  142.  *
  143.  * evaluate kind of uri
  144.  */
  145. URIKIND uri_kind(STRPTR uri)
  146. {
  147.     URIKIND kind = URI_abs;
  148.  
  149.     if (upstrncmp(uri, ABSURI_ID, strlen(ABSURI_ID)))
  150.     {
  151.         if (uri[0] == '/')
  152.             kind = URI_relserv;
  153.         else
  154.         {
  155.             STRPTR colon_pos = strchr(uri, ':');
  156.             STRPTR slash_pos = strchr(uri, '/');
  157.  
  158.             if (colon_pos)
  159.                 if (slash_pos)
  160.                     if (colon_pos < slash_pos)
  161.                         kind = URI_ext;
  162.                     else
  163.                         kind = URI_rel;
  164.                 else
  165.                     kind = URI_ext;
  166.             else
  167.                 kind = URI_rel;
  168.         }
  169.     }
  170.     return (kind);
  171. }
  172.  
  173. /*
  174.  * convert uri to filename in destination-dir
  175.  */
  176. static VOID conv_hscuri2fileNuri(HSCPRC * hp, EXPSTR * dest_uri, EXPSTR * dest_fname, STRPTR uri)
  177. {
  178.     EXPSTR *rel_path = init_estr(32);   /* relative path */
  179.     URIKIND kind = uri_kind(uri);
  180.  
  181.     clr_estr(dest_uri);
  182.     clr_estr(dest_fname);
  183.  
  184.     /* if a <BASE HREF=".."> was found before,
  185.      * therefor treat URI as absolute
  186.      */
  187.     if (hp->docbase_set)
  188.         kind = URI_ext;
  189.  
  190.     /* evaluate kind of URI */
  191.     if (kind == URI_abs)
  192.         uri++;                  /* skip ":" */
  193.  
  194.     /* reset destination filename */
  195.     set_estr(dest_fname, "");
  196.  
  197.     if (kind == URI_abs)
  198.     {
  199.         /*
  200.          * parse absolute uri
  201.          */
  202.         D(fprintf(stderr, DHL "exists `%s' [abs]\n", uri));
  203.  
  204.         /* check if local uri exists */
  205.         {
  206.             EXPSTR *dest_relfname = init_estr(32);
  207.             conv_uri2path(dest_relfname, uri);
  208.  
  209.             estrcpy(dest_fname, hp->destdir);
  210.             estrcat(dest_fname, dest_relfname);
  211.  
  212.             del_estr(dest_relfname);
  213.         }
  214.  
  215.         D(fprintf(stderr, DHL "  -> file `%s'\n",
  216.                   estr2str(dest_fname)));
  217.  
  218.         /* create path of destination file */
  219.         estrcpy(dest_uri, hp->reldir);
  220.         app_estr(dest_uri, uri);
  221.  
  222.         get_relfname(rel_path, uri, estr2str(hp->reldir));
  223.         D(fprintf(stderr, DHL "  -> rel. path `%s' (`%s')\n",
  224.                   estr2str(rel_path),
  225.                   estr2str(hp->reldir)));
  226.  
  227.         /* debug */
  228.         D(fprintf(stderr, DHL "  -> real path `%s'\n", uri));
  229.  
  230.         /* convert (filesystem depending) path to uri */
  231.         conv_path2uri(dest_uri, estr2str(rel_path));
  232.  
  233.         /* debug */
  234.         D(fprintf(stderr, DHL "  -> real uri  `%s'\n",
  235.                   estr2str(dest_uri)));
  236.     }
  237.     else if (kind == URI_rel)
  238.     {
  239.         /*
  240.          * parse relative uri
  241.          */
  242.         EXPSTR *uri_path = init_estr(32);
  243.  
  244.         /* debug */
  245.         D(fprintf(stderr, DHL "exists `%s' [rel]\n", uri));
  246.  
  247.         /* create local filename */
  248.         conv_uri2path(uri_path, uri);
  249.         estrcat(dest_fname, hp->destdir);
  250.         estrcat(dest_fname, hp->reldir);
  251.         estrcat(dest_fname, uri_path);
  252.  
  253.         /* create uri (only copy path) */
  254.         set_estr(dest_uri, uri);
  255.  
  256.         /* debug */
  257.         D(
  258.              {
  259.              fprintf(stderr, DHL "  -> real path `%s'\n",
  260.                      estr2str(dest_fname));
  261.              fprintf(stderr, DHL "  -> real uri  `%s'\n",
  262.                      estr2str(dest_uri));
  263.              }
  264.         );
  265.  
  266.         del_estr(uri_path);
  267.     }
  268.     else
  269.     {
  270. #if 0
  271.         STRARR tmp[300];
  272.  
  273.         strcpy(tmp, "unknown uri-kind: ");
  274.         strcat(tmp, uri);
  275.         panic(tmp);
  276. #endif
  277.         set_estr(dest_uri, uri);
  278.         set_estr(dest_fname, "");
  279.     }
  280.  
  281.     /* free resources */
  282.     del_estr(rel_path);
  283. }
  284.  
  285. VOID conv_hscuri2file(HSCPRC * hp, EXPSTR * dest_fname, STRPTR uri)
  286. {
  287.     EXPSTR *dest_uri = init_estr(64);
  288.     conv_hscuri2fileNuri(hp, dest_uri, dest_fname, uri);
  289.     del_estr(dest_uri);
  290. }
  291.  
  292. /*
  293.  * parse_uri
  294.  *
  295.  * check uri-string for syntatic correctnes;
  296.  * if the uri refers to an local file, convert its absolute
  297.  * path to a relative path and check its existence.
  298.  *
  299.  * uri = "rsrc_type://host.domain:port/pathname#id"
  300.  */
  301. VOID parse_uri(HSCPRC * hp, EXPSTR * dest_uri, STRPTR uri)
  302. {
  303.     STRPTR host = NULL;
  304.     STRPTR port = NULL;
  305.     STRPTR path = NULL;
  306.     STRPTR name = NULL;
  307.  
  308.     clr_estr(dest_uri);
  309.  
  310.     if (uri)
  311.     {
  312.         /* check for valid uri */
  313.         URIKIND kind = uri_kind(uri);
  314.         if ((kind == URI_ext) || (kind == URI_relserv))
  315.         {
  316.             if (kind == URI_ext)
  317.             {
  318.                 /*
  319.                  * check global uri
  320.                  */
  321.                 if (!host)
  322.                     host = "";
  323.                 if (!port)
  324.                     port = "";
  325.                 if (!host)
  326.                     host = "";
  327.  
  328.                 /*
  329.                  * TODO: parse global uris
  330.                  */
  331.             }
  332.             set_estr(dest_uri, uri);
  333.         }
  334.         else
  335.         {
  336.             /*
  337.              * check local uri
  338.              */
  339.  
  340.             /* destination file name that's existence is checked if
  341.              * chkuri is enabled */
  342.             EXPSTR *dest_fname = init_estr(32);
  343.             STRPTR noabsuri = uri;
  344.  
  345.             /* evaluate kind of URI */
  346.             if (kind == URI_abs)
  347.                 noabsuri++;     /* skip ":" */
  348.  
  349.             /* extract path and #name */
  350.             if (noabsuri[0] == '#')
  351.             {
  352.                 path = NULL;
  353.                 name = noabsuri + 1;    /* skip '#' for ":#id" */
  354.             }
  355.             else
  356.             {
  357.                 path = strtok(uri, "#");
  358.                 name = strtok(NULL, "");
  359.             }
  360.  
  361.             if (path)
  362.             {
  363.                 FILE *exist = NULL;
  364.  
  365.                 /*
  366.                  * check existence of local uri
  367.                  */
  368.                 conv_hscuri2fileNuri(hp, dest_uri, dest_fname, path);
  369.                 if (hp->chkuri
  370.                     && !(hsc_get_msg_ignore(hp, MSG_NO_URIPATH)))
  371.                 {
  372.                     exist = fopen(estr2str(dest_fname), "r");
  373.                     if (!exist)
  374.                     {
  375.                         hsc_msg_nouri(hp, estr2str(dest_fname), uri, NULL);
  376.                     }
  377.                     else
  378.                     {
  379.                         fclose(exist);
  380.  
  381.                         /* check id */
  382.                         if (hp->chkid && name)
  383.                         {
  384.                             STRPTR doc_fname = estr2str(dest_fname);
  385.  
  386.                             if (!fnamecmp(hp->project->document->docname,
  387.                                           doc_fname))
  388.                             {
  389.                                 /* filename references current document */
  390.                                 add_local_idref(hp, name);
  391.                             }
  392.                             else
  393.                             {
  394.                                 /* filename reference other document;
  395.                                  * lookup project-data */
  396.                                 switch (check_document_id(hp->project,
  397.                                                           doc_fname, name))
  398.                                 {
  399.                                 case ERR_CDI_OK:
  400.                                     D(fprintf(stderr, DHL "  id ok\n"));
  401.                                     break;
  402.                                 case ERR_CDI_NoID:
  403.                                     hsc_message(hp, MSG_UNKN_ID,
  404.                                                 "unknown %i", name);
  405.                                     break;
  406.                                 case ERR_CDI_NoDocumentEntry:
  407.                                     hsc_message(hp, MSG_NO_DOCENTRY,
  408.                                                 "no entry for document %q "
  409.                                                 "to check %i",
  410.                                                 estr2str(dest_fname),
  411.                                                 name);
  412.                                     break;
  413.                                 default:
  414.                                     panic("unknown returncode");
  415.                                     break;
  416.                                 }
  417.                             }
  418.                         }
  419.                     }
  420.                 }
  421.             }
  422.             else
  423.             {
  424.                 /* check existence ID referencing into current file */
  425.                 if (hp->chkid && name)
  426.                     add_local_idref(hp, name);
  427.             }
  428.  
  429.             /* add #name part */
  430.             if (name)
  431.             {
  432.                 app_estrch(dest_uri, '#');
  433.                 app_estr(dest_uri, name);
  434.             }
  435.             /* free resources */
  436.             del_estr(dest_fname);
  437.         }                       /* else (rsrc) */
  438.     }                           /* if (uri) */
  439. }
  440.  
  441.